// pagesE/UpdateDownloader/index.js（修复版本最新仍跳转问题）
import CONFIG from "./config/index.js";
import {
  downloadAndInstallApk,
  downloadAndInstallWgt,
  openAppStore
} from "./utils/updateUtils.js";

// 全局状态管理：补充注释，明确字段用途
let globalUpdateState = {
  mask: null, // 原生更新遮罩实例
  isUpdating: false, // 防重复更新锁（true=更新中）
  updateTaskId: null, // 下载任务ID（用于中断任务）
  completeDialogContext: null, // 安装完成弹窗上下文
  isInitialLoaded: false // 初始更新检查完成标记
};

/**
 * 启动应用更新流程（对外暴露核心方法）
 * @param {Object} options - 可选配置：回调函数、自定义页面等
 */
export function startUpdate(options = {}) {
  // 解构配置项：优化默认值优先级，补充类型校验
  const {
    onProgress = (progress) => console.log("更新进度：", progress),
    onComplete = () => console.log("更新流程完成"),
    onError = (err) => console.error("更新错误：", err),
    // 安装完成回调：默认强制更新2秒后重启
    onInstallComplete = (isForce) => {
      if (isForce) {
        setTimeout(() => {
          try {
            plus.runtime.restart();
          } catch (error) {
            console.warn("应用重启失败：", error);
          }
        }, 2000);
      }
    },
    // 初始检查提示：支持外部关闭（传递空函数）
    onInitialLoading = () => {
      // uni.showToast({
      //   title: "检查更新中...",
      //   icon: "loading",
      //   mask: true,
      //   duration: 3000
      // });
    },
    // 安装完成弹窗：仅非强制静默更新显示（优化作用域）
    showInstallCompleteDialog = (isForce, updateDesc, isSilent) => {
      // 强制/非静默更新不弹窗，直接执行回调
      if (isForce || !isSilent) {
        onInstallComplete(isForce);
        return;
      }

      // 非强制静默更新弹窗：简化文案逻辑
      const pureTextDesc = extractPureText(updateDesc);
      const dialogConfig = {
        title: "更新成功",
        content: `本次更新已完成，您可以继续使用应用\n\n更新内容：\n${pureTextDesc}`,
        showCancel: false,
        confirmText: "我知道了",
        confirmColor: "#007AFF",
        mask: true,
        success: (res) => res.confirm && onInstallComplete(isForce),
        fail: (error) => {
          console.error("安装完成弹窗失败：", error);
          onInstallComplete(isForce);
        }
      };

      clearCompleteDialog();
      const dialog = uni.showModal(dialogConfig);
      if (dialog) globalUpdateState.completeDialogContext = dialog;
    },
    // 轻提示：统一文本处理，避免溢出
    showToast = (msg) => {
      const pureText = extractPureText(msg).slice(0, 50); // 限制最大长度
      uni.showToast({
        title: pureText,
        icon: "none",
        duration: pureText.includes("\n") ? 3000 : 2000,
        mask: true
      });
    },
    // 强制更新页面：优先级 -> 专属配置 > 通用更新页 > 旧配置 > 默认页
    forceUpdatePage = CONFIG.forceUpdatePage ||
      CONFIG.updatePage ||
      CONFIG.forcePage ||
      "/pages/UpdateForce/index",
    // 无更新回调：支持外部自定义提示
    onNoUpdate = () => console.log("当前已是最新版本（或未发行）")
  } = options;

  /**
   * 工具函数：提取纯文本（清理HTML标签和特殊字符）
   * @param {string} html - 含HTML标签的文本
   * @returns {string} 纯文本内容
   */
  function extractPureText(html) {
    if (!html || typeof html !== "string") return "优化应用体验";
    return html
      .replace(/<[^>]+>/gi, "") // 移除HTML标签
      .replace(/&nbsp;|&lt;|&gt;/gi, (match) => {
        // 替换HTML实体
        const entityMap = { "&nbsp;": " ", "&lt;": "<", "&gt;": ">" };
        return entityMap[match] || match;
      })
      .replace(/\s+/g, " ") // 合并多空格
      .replace(/\n+/g, "\n") // 合并多换行
      .trim(); // 清理首尾空白
  }

  /**
   * 工具函数：清除安装完成弹窗（兼容不同UniApp版本）
   */
  function clearCompleteDialog() {
    if (!globalUpdateState.completeDialogContext) return; // 空值快速返回

    try {
      // 优先使用弹窗实例close方法，其次用uni.hideModal
      if (typeof globalUpdateState.completeDialogContext.close === "function") {
        globalUpdateState.completeDialogContext.close();
      } else if (typeof uni.hideModal === "function") {
        uni.hideModal();
      }
    } catch (error) {
      console.warn("清除弹窗失败：", error);
    } finally {
      globalUpdateState.completeDialogContext = null; // 无论成败均重置
    }
  }

  /**
   * 工具函数：显示更新遮罩（强制更新专用，禁止背景操作）
   * @param {string} title - 遮罩提示文本
   */
  function showUpdateMask(title = "更新中...") {
    // 防重复创建：已存在遮罩/非App环境/更新中时拦截
    if (
      globalUpdateState.mask ||
      typeof plus === "undefined" ||
      globalUpdateState.isUpdating
    ) {
      console.log("遮罩创建拦截：已存在或更新中");
      return;
    }

    try {
      globalUpdateState.mask = plus.nativeUI.showWaiting(title, {
        modal: true, // 禁止背景操作
        backdrop: "rgba(0,0,0,0.7)", // 半透明背景
        width: "80%", // 遮罩宽度
        height: "120px", // 遮罩高度
        textColor: "#FFFFFF", // 文本颜色
        textSize: "16px", // 文本大小
        loading: { color: "#FFFFFF" } // 加载动画颜色
      });
    } catch (error) {
      console.warn("显示遮罩失败：", error);
      showToast("更新准备中..."); // 降级提示
    }
  }

  /**
   * 工具函数：关闭所有弹窗和遮罩（统一清理）
   */
  function closeAllOverlays() {
    clearCompleteDialog(); // 清除完成弹窗
    // 清除更新遮罩
    if (globalUpdateState.mask && typeof plus !== "undefined") {
      try {
        globalUpdateState.mask.close();
      } catch (error) {
        console.warn("关闭遮罩失败：", error);
      } finally {
        globalUpdateState.mask = null;
      }
    }
    uni.hideToast(); // 关闭轻提示
  }

  /**
   * 工具函数：清除更新状态（防重复+异常恢复）
   * @param {boolean} isInterruptTask - 是否中断下载任务
   */
  function clearUpdateState(isInterruptTask = false) {
    closeAllOverlays();
    // 中断下载任务（仅当需要且任务ID存在时）
    if (
      isInterruptTask &&
      globalUpdateState.updateTaskId &&
      typeof plus !== "undefined"
    ) {
      try {
        plus.downloader.clear(globalUpdateState.updateTaskId);
        console.log(`中断下载任务：${globalUpdateState.updateTaskId}`);
      } catch (error) {
        console.warn("中断任务失败：", error);
      }
    }
    // 重置核心状态（保留其他字段，避免覆盖）
    globalUpdateState.isUpdating = false;
    globalUpdateState.updateTaskId = null;
    globalUpdateState.isInitialLoaded = false;
  }

  /**
   * 【新增】工具函数：判断强制更新是否真正需要执行（核心修复）
   * @param {Object} local - 本地版本信息 { version: string, code: number }
   * @param {Object} remote - 远程版本信息 { version: string, code: number }
   * @returns {boolean} 是否需要执行强制更新（远程版本 > 本地版本）
   */
  function isForceUpdateNeeded(local, remote) {
    // 1. 版本码对比（数字对比，优先级最高）
    if (local.code > 0 && remote.code > 0) {
      const isCodeNeed = remote.code > local.code;
      console.log(
        `【强制更新校验】版本码对比：本地=${local.code}，远程=${remote.code}，需强制更新=${isCodeNeed}`
      );
      return isCodeNeed;
    }
    // 2. 版本名对比（字符串分割对比，兜底）
    const compareVer = (v1, v2) => {
      const v1Arr = v1.split(".").map(Number);
      const v2Arr = v2.split(".").map(Number);
      const maxLen = Math.max(v1Arr.length, v2Arr.length);
      for (let i = 0; i < maxLen; i++) {
        const n1 = v1Arr[i] || 0;
        const n2 = v2Arr[i] || 0;
        if (n1 > n2) return 1;
        if (n1 < n2) return -1;
      }
      return 0;
    };
    const isVerNeed = compareVer(remote.version, local.version) > 0;
    console.log(
      `【强制更新校验】版本名对比：本地=${local.version}，远程=${remote.version}，需强制更新=${isVerNeed}`
    );
    return isVerNeed;
  }

  /**
   * 核心工具：强制更新专用跳转（独立逻辑，优先级最高）
   * @param {Object} params - 跳转参数
   * @param {Object} params.updateInfo - 远程更新信息
   * @param {string} params.reason - 跳转原因（normal/wgt_incompatible/type_mismatch等）
   * @param {string} [params.currentApkVer] - 当前APK版本（跨版本时必传）
   * @param {string} params.updateType - 更新类型（apk/wgt）
   */
  function forceUpdateJump({ updateInfo, reason, currentApkVer, updateType }) {
    // 防重复跳转：更新中时拦截
    if (globalUpdateState.isUpdating) {
      showToast("已在处理强制更新，请稍候");
      return;
    }
    globalUpdateState.isUpdating = true;

    // 强制更新提示文案：按原因区分（优化用户感知）
    const reasonTips = {
      normal: `检测到${updateType.toUpperCase()}强制更新，即将跳转...`,
      wgt_incompatible: "当前版本过低，需先更新基础版本，即将跳转...",
      type_mismatch: "更新包类型调整，即将跳转处理...",
      version_consistent: "检测到强制更新指令，即将跳转..."
    };
    const jumpTip = reasonTips[reason] || reasonTips.normal;
    showToast(jumpTip);

    // 构建跳转参数：双重编码避免特殊字符截断（优化参数传递）
    const encodedUpdateInfo = encodeURIComponent(JSON.stringify(updateInfo));
    let jumpUrl = `${forceUpdatePage}?updateInfo=${encodedUpdateInfo}&isForce=true&updateType=${updateType}&reason=${reason}`;
    // 跨版本场景补充当前APK版本
    if (currentApkVer) jumpUrl += `&currentApkVer=${currentApkVer}`;

    // 延迟跳转：确保用户看到提示（1秒后强制跳转，不可取消）
    setTimeout(() => {
      uni.reLaunch({
        url: jumpUrl,
        success: () => {
          console.log(`【强制更新】跳转成功，目标页：${forceUpdatePage}`);
          // 延迟清理状态：确保页面切换完成（800ms兼容低端机）
          setTimeout(clearUpdateState, 800);
        },
        fail: (error) => {
          console.error(`【强制更新】跳转失败：`, error);
          showToast("强制更新跳转失败，请重试");
          // 跳转失败重置状态，允许用户再次触发
          globalUpdateState.isUpdating = false;
          clearUpdateState();
        }
      });
    }, 1000);
  }

  /**
   * 核心函数：更新逻辑处理（强制更新优先校验）
   * @param {Object} updateInfo - 格式化后的远程更新信息
   * @param {string} localVersion - 本地应用版本
   * @param {Object} appInfo - 本地应用信息（versionCode等）
   */
  function handleUpdate(updateInfo, localVersion, appInfo) {
    // 工具子函数：版本号清洗（统一格式，避免异常字符）
    const sanitizeVersion = (version) => {
      if (!version) return "0.0.0";
      return (
        version
          .trim()
          .replace(/[^\d.]/g, "") // 保留数字和点
          .replace(/^\.+|\.+$/g, "") // 去除首尾点
          .replace(/\.{2,}/g, ".") || // 多个点合并为一个
        "0.0.0"
      );
    };

    // 1. 解构远程更新信息：优先提取强制更新标记（核心控制字段）
    const {
      edition_urls = [],
      package_type = 1, // 1=WGT，0=APK（配置类型）
      edition_force = 0, // 1=强制更新（核心标记）
      edition_silence = 0, // 1=静默更新（仅WGT）
      describe = "优化应用体验", // 更新描述
      edition_name = "1.0.0", // 远程版本名
      edition_number = "100", // 远程版本码
      edition_issue = 0, // 1=已发行（必为1才更新）
      min_support_apk_version = "0.0.0", // WGT支持的最小APK版本
      max_support_apk_version = "999.999.999" // WGT支持的最大APK版本
    } = updateInfo || {}; // 空值容错，避免解构报错

    // 2. 预处理本地/远程版本信息（用于后续校验）
    const localVer = sanitizeVersion(localVersion);
    const localCode = parseInt(
      (appInfo.versionCode || 0).toString().replace(/[^\d]/g, ""),
      10
    );
    const remoteVer = sanitizeVersion(edition_name);
    const remoteCode = parseInt(
      (edition_number || 0).toString().replace(/[^\d]/g, ""),
      10
    );
    // 封装版本信息为对象（便于传递）
    const localVersionInfo = { version: localVer, code: localCode };
    const remoteVersionInfo = { version: remoteVer, code: remoteCode };

    // 3. 强制更新前置校验：仅当“已发行+强制标记=1+远程版本>本地版本”时才处理
    const isForceUpdate = edition_force === 1;
    const isIssued = edition_issue === 1;
    // 【核心修复】增加“远程版本是否高于本地”的校验
    const needForceHandle =
      isForceUpdate &&
      isIssued &&
      isForceUpdateNeeded(localVersionInfo, remoteVersionInfo);
    console.log(
      `【强制更新前置校验】结果：isForce=${isForceUpdate}，isIssued=${isIssued}，needForceHandle=${needForceHandle}`
    );

    // 4. 处理更新地址：过滤空地址/非字符串地址（容错）
    const validUrls = (() => {
      if (typeof edition_urls === "string")
        return edition_urls.trim() ? [edition_urls.trim()] : [];
      return Array.isArray(edition_urls)
        ? edition_urls.filter(
            (url) => url && typeof url === "string" && url.trim()
          )
        : [];
    })();

    // 5. 纠正更新类型：按文件后缀覆盖配置类型（避免配置错误）
    let updateType = "wgt"; // 默认WGT
    if (validUrls.length > 0) {
      const firstUrl = validUrls[0].toLowerCase();
      if (firstUrl.endsWith(".apk")) {
        updateType = "apk";
        console.warn(`【更新工具】纠正类型：配置=${package_type} → 实际=APK`);
      } else if (firstUrl.endsWith(".wgt")) {
        updateType = "wgt";
        console.log(`【更新工具】确认类型：WGT`);
      } else {
        console.error(`【更新工具】未知类型：${firstUrl}，默认使用WGT`);
      }
    }

    // 6. 强制更新专属：类型不匹配仍跳转（但需先满足“远程版本>本地”）
    if (needForceHandle && validUrls.length > 0) {
      const firstUrl = validUrls[0].toLowerCase();
      const urlType = firstUrl.endsWith(".apk")
        ? "apk"
        : firstUrl.endsWith(".wgt")
        ? "wgt"
        : "";
      if (urlType && urlType !== updateType) {
        const errMsg = `强制更新类型调整：配置=${updateType.toUpperCase()} → 实际=${urlType.toUpperCase()}`;
        console.error(`【强制更新】${errMsg}`);
        showToast(errMsg);
        // 携带实际类型跳转，让目标页处理
        forceUpdateJump({
          updateInfo,
          reason: "type_mismatch",
          updateType: urlType
        });
        return;
      }
    }

    // 7. 版本对比：判断是否需要更新（通用逻辑，非强制也适用）
    const isNeedUpdate =
      validUrls.length > 0 &&
      ((remoteCode > 0 && localCode > 0 && remoteCode > localCode) ||
        (() => {
          const v1Arr = localVer.split(".").map(Number);
          const v2Arr = remoteVer.split(".").map(Number);
          const maxLen = Math.max(v1Arr.length, v2Arr.length);
          for (let i = 0; i < maxLen; i++) {
            const n1 = v1Arr[i] || 0;
            const n2 = v2Arr[i] || 0;
            if (n1 > n2) return false;
            if (n1 < n2) return true;
          }
          return false;
        })());

    // 日志输出：优化格式，突出强制更新信息（便于调试）
    console.log("【更新工具】版本对比结果：", {
      local: localVersionInfo,
      remote: {
        ...remoteVersionInfo,
        type: updateType.toUpperCase(),
        isForce: isForceUpdate,
        isSilent: edition_silence === 1,
        isIssued: isIssued
      },
      isNeedUpdate,
      needForceHandle, // 新增：输出强制更新是否需要处理
      forceUpdatePage,
      validUrlsCount: validUrls.length
    });

    // 场景1：无需更新（非强制+强制但版本一致均进入）
    if (!isNeedUpdate || !isIssued) {
      // 【核心修复】强制更新但版本一致时，不跳转，执行onNoUpdate
      if (isForceUpdate && isIssued && !needForceHandle) {
        console.log(
          `【强制更新】版本一致（本地=${localVer}，远程=${remoteVer}），无需跳转`
        );
        showToast("当前已是最新版本（强制更新校验通过）");
        onNoUpdate();
        clearUpdateState();
        return;
      }
      // 非强制更新：正常终止
      onNoUpdate();
      clearUpdateState();
      return;
    }

    // 场景2：强制更新（所有子场景统一跳转，优先级最高）
    if (needForceHandle) {
      // 子场景2.1：WGT强制更新 - 跨APK版本不兼容
      if (updateType === "wgt") {
        const isApkCompatible = (() => {
          const v1Arr = localVer.split(".").map(Number);
          const minArr = sanitizeVersion(min_support_apk_version)
            .split(".")
            .map(Number);
          const maxArr = sanitizeVersion(max_support_apk_version)
            .split(".")
            .map(Number);
          const maxLen = Math.max(v1Arr.length, minArr.length, maxArr.length);
          let isMinOk = true;
          let isMaxOk = true;
          for (let i = 0; i < maxLen; i++) {
            const n1 = v1Arr[i] || 0;
            const min = minArr[i] || 0;
            const max = maxArr[i] || 0;
            if (n1 < min) isMinOk = false;
            if (n1 > max) isMaxOk = false;
          }
          return isMinOk && isMaxOk;
        })();
        if (!isApkCompatible) {
          console.log(`【强制更新】WGT跨版本不兼容，跳转APK更新`);
          forceUpdateJump({
            updateInfo,
            reason: "wgt_incompatible",
            currentApkVer: localVer,
            updateType: "apk" // 强制跳转APK更新页
          });
          return;
        }
      }

      // 子场景2.2：正常强制更新（APK/WGT通用）
      console.log(`【强制更新】正常触发，跳转目标页`);
      forceUpdateJump({
        updateInfo,
        reason: "normal",
        updateType: updateType
      });
      return;
    }

    // 场景3：非强制静默更新（仅WGT，后台执行）
    const isSilent = updateType === "wgt" && edition_silence === 1;
    if (isSilent) {
      // 静默更新无需跳转，直接执行下载
      if (globalUpdateState.isUpdating) {
        // showToast("已在更新中，请勿重复操作");
        return;
      }
      globalUpdateState.isUpdating = true;
      // showToast("开始静默更新...");

      downloadAndInstall("wgt", validUrls, {
        onProgress,
        onComplete: () => {
          // showInstallCompleteDialog(false, describe, isSilent);
          onComplete();
          clearUpdateState();
          plus.runtime.restart();
        },
        onError: (error) => {
          showToast(`静默更新失败：${error.message || "未知错误"}`);
          onError(error);
          clearUpdateState(true);
        }
      });
      return;
    }

    // 场景4：非强制非静默更新（跳转通用更新页）
    if (globalUpdateState.isUpdating) {
      showToast("已在更新中，请勿重复操作");
      return;
    }
    globalUpdateState.isUpdating = true;
    const tip = `发现${updateType.toUpperCase()}更新，即将跳转...`;
    showToast(tip);

    setTimeout(() => {
      // 跳转通用更新页：优先级 -> 通用配置 > 强制更新页
      const targetPage = CONFIG.updatePage || forceUpdatePage;
      const encodedUpdateInfo = encodeURIComponent(JSON.stringify(updateInfo));
      uni.reLaunch({
        url: `${targetPage}?updateInfo=${encodedUpdateInfo}&isForce=false&updateType=${updateType}`
      });
      setTimeout(clearUpdateState, 800);
    }, 1000);
  }

  /**
   * 工具函数：下载安装统一封装（兼容WGT/APK，多地址容错）
   * @param {string} type - 更新类型（wgt/apk）
   * @param {Array} urls - 有效下载地址列表
   * @param {Object} callbacks - 回调函数集合
   */
  function downloadAndInstall(type, urls, { onProgress, onComplete, onError }) {
    // 入参校验：避免无效调用
    if (!urls || !urls.length) {
      onError(new Error("更新地址为空或无效"));
      showToast("更新地址异常");
      clearUpdateState();
      return;
    }
    if (
      typeof onProgress !== "function" ||
      typeof onComplete !== "function" ||
      typeof onError !== "function"
    ) {
      console.error("【更新工具】下载安装：回调必须为函数");
      return;
    }

    // 选择下载方法（严格按类型匹配）
    const downloadFn =
      type === "wgt" ? downloadAndInstallWgt : downloadAndInstallApk;
    console.log(`【更新工具】开始下载${type.toUpperCase()}，地址：${urls[0]}`);

    // 多地址容错：失败后自动尝试下一个地址
    let currentIndex = 0;
    const tryDownload = (index) => {
      if (index >= urls.length) {
        onError(new Error("所有更新地址均下载失败"));
        return;
      }

      // 传递单个地址数组（匹配updateUtils.js的入参要求）
      downloadFn(
        [urls[index]],
        (progress, taskId) => {
          globalUpdateState.updateTaskId = taskId; // 记录任务ID
          onProgress(progress, taskId);
        },
        () => {
          console.log(`【更新工具】${type.toUpperCase()}下载安装成功`);
          onComplete();
        },
        (error) => {
          console.warn(
            `【更新工具】${type.toUpperCase()}下载失败（${index + 1}/${
              urls.length
            }）：`,
            error
          );
          tryDownload(index + 1); // 尝试下一个地址
        }
      );
    };

    tryDownload(currentIndex);
  }

  // ---------------------- 流程入口：防误触+容错 ----------------------
  // 非App环境拦截（仅支持App端更新）
  if (typeof plus === "undefined") {
    showToast("仅 App 端支持更新功能");
    return;
  }

  // 执行初始检查提示
  onInitialLoading();

  // 获取本地应用信息（版本号、版本码等）
  plus.runtime.getProperty(plus.runtime.appid, (appInfo) => {
    // 容错：获取应用信息失败时终止
    if (!appInfo) {
      console.error("【更新工具】获取本地应用信息失败");
      uni.hideToast();
      showToast("获取应用信息失败，无法检查更新");
      clearUpdateState();
      return;
    }

    const localVersion = appInfo.version || CONFIG.defaultVersion || "0.0.0";
    const updateRequest = CONFIG.updateRequest || {};

    // 校验更新接口配置（必传url）
    if (!updateRequest.url) {
      console.error("【更新工具】错误：更新接口地址未配置");
      uni.hideToast();
      showToast("更新配置异常，请联系管理员");
      clearUpdateState();
      return;
    }

    // 请求远程更新信息（优化header/data合并，避免undefined）
    console.log("【更新工具】请求远程更新信息...", {
        edition_type: plus.runtime.appid,
        version_type: uni.getSystemInfoSync().platform,
        edition_number: appInfo.versionCode || 0,
        ...(updateRequest.data || {})
      })
    uni.request({
      url: updateRequest.url,
      method: updateRequest.method || "GET",
      header: {
        "Content-Type": "application/json",
        ...(updateRequest.header || {})
      },
      data: {
        edition_type: plus.runtime.appid,
        version_type: uni.getSystemInfoSync().platform,
        edition_number: appInfo.versionCode || 0,
        ...(updateRequest.data || {})
      },
      timeout: 8000, // 超时时间：8秒（避免长时间阻塞）
      success: (res) => {
        uni.hideToast();
        globalUpdateState.isInitialLoaded = true;

        // 格式化更新信息（支持外部自定义映射）
        const formattedUpdateInfo =
          typeof CONFIG.infoMapFun === "function"
            ? CONFIG.infoMapFun(res.data || {})
            : res.data || {};

        // 处理更新逻辑（强制更新优先）
        handleUpdate(formattedUpdateInfo, localVersion, appInfo);
      },
      fail: (error) => {
        uni.hideToast();
        console.error("【更新工具】请求更新信息失败：", error);
        showToast(`检查更新失败：${error.errMsg || "网络异常"}`);
        clearUpdateState();
      }
    });
  });
}
